<?php
/**
 * Created by PhpStorm.
 * User: BlueIdeaLirui
 * Date: 2019/09/04
 * Time: 14:58
 */

namespace business\elasticsearch\services;

use business\elasticsearch\repositories\MaterialBasicRepository;

class MaterialService
{
    /**
     * 返回材料列表
     * @param $keyword
     * @param $onlyAreaCode
     * @param $materialCategoryCode
     * @param $page
     * @param $pageSize
     * @throws \yii\db\Exception
     */
    public function getList
    (
        $keyword,
        $onlyAreaCode,
        $materialCategoryCode,
        $page,
        $pageSize
    ) {
        $page = max($page, 1);

        $query = [];

        $keyword = trim($keyword);

        // 构建查询条件
        $this->builderQueryConds($query, $keyword, $onlyAreaCode, $materialCategoryCode);

        $from = ($page - 1) * $pageSize;

        $include = [];

        //高亮处理
        $highlight = [
//            'require_field_match' => false,
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields"=>[
                'materialName' => new \stdClass(),
                'materialCategory' => new \stdClass(),
            ]
        ];

        list($total, $data) = (new MaterialBasicRepository())->queryList($query, $include, $from, $pageSize, $highlight);

        $result = ['resultNum' => $total, 'resultSet' => null];

        if (!empty($data)) {
            foreach ($data as $dv) {
                $tmp = $dv['_source'];
                if (!empty($dv['highlight'])) {
                    foreach ($dv['highlight'] as $key => $value) {
                        $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';
                    }
                }
                $result['resultSet'][] = $tmp;
            }
        }

        return $result;
    }

    /**
     * 构建查询条件
     * @param array $query
     * @param $keyword
     * @param $onlyAreaCode
     * @param $materialCategoryCode
     * @throws \yii\db\Exception
     */
    public function builderQueryConds
    (
        &$query = [],
        $keyword,
        $onlyAreaCode,
        $materialCategoryCode
    ) {
        $hasCategoryWords = false;

        if (!empty($keyword)) {
            $hasCategoryWords = $this->hasCategoryWords($keyword);
        }

        $bool = [];

        $boolKey = 0;

        // 构建项目地区查询
        $this->builerAreaQuery($bool, $boolKey, $onlyAreaCode);
        // 构建材料分类code查询
        $this->builerCategoryQuery($bool, $boolKey, $materialCategoryCode);

        !empty($bool) && $query['bool'] = $bool;

        // 构建关键词查询
        $this->builerKeywordQuery($query, $hasCategoryWords, $keyword);
    }

    /**
     * 构建关键词查询
     * @param array $query
     * @param $hasCategoryWords
     * @param $keyword
     */
    protected function builerKeywordQuery
    (
        &$query = [],
        $hasCategoryWords,
        $keyword
    ) {
        if (!empty($keyword)) {
            $query['bool']['should'] = [
                ['match' => ['materialName' => ['query' => $keyword]]],
                ['match' => ['materialCategory' => ['query' => $keyword, 'boost' => 2]]],
            ];

            $query['bool']['minimum_should_match'] = 1;
        }
    }

    /**
     * 构建材料分类code查询
     * @param array $bool
     * @param $boolKey
     * @param $categoryCode
     */
    protected function builerCategoryQuery
    (
        &$bool = [],
        &$boolKey,
        $categoryCode
    ) {
        if (!empty($categoryCode)) {
            $bool['filter']['bool']['must'][$boolKey]['bool']['must'][] = [
                'term' => [
                    'materialCategoryCode' => $categoryCode
                ]
            ];
            $boolKey++;
        }
    }

    /**
     * 构建材料区域查询
     * @param array $bool
     * @param $region
     */
    protected function builerAreaQuery
    (
        &$bool = [],
        &$boolKey,
        $region
    ) {
        if (!empty($region)) {
            $region = explode(',', $region);
            foreach ($region as $item) {
                $keys = ['areaCode'];
                if (!empty($keys)) {
                    array_walk($keys,
                        function
                        (
                            $value
                        )
                        use (
                            &$bool,
                            &$boolKey,
                            $item
                        ) {
                            $bool['filter']['bool']['must'][$boolKey]['bool']['should'][] = [
                                'match_phrase' => [
                                    $value => $item
                                ]
                            ];
                        });
                }
            }
            $boolKey++;
        }
    }

    /**
     * 判断搜索关键词是否是分类词
     * @throws \yii\db\Exception
     */
    protected function hasCategoryWords($keyword = '')
    {
        $sql = "select * from `b2b_parameter`.`bsp_basic_forest` where category_status=1 
                and category_name like '%".$keyword."%'";
        $data = \Yii::$app->db->createCommand($sql)->queryAll();
        return empty($data) ? false : true;
    }
}
